package com.veetao.api.filter;

import java.lang.ref.WeakReference;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.veetao.api.consts.HttpConstants;
import com.veetao.api.model.ApiResult;
import com.veetao.api.model.ApiResultCode;
import com.veetao.api.service.CommandLookupService;
import com.veetao.api.utils.McpUtils;
import com.veetao.api.utils.RequestUtils;

@Component
public class SignatureFrequencyChecker extends ApiRequestChecker {
	private static final Log logger = LogFactory.getLog(SignatureFrequencyChecker.class);
	private WeakReference<ConcurrentHashMap<String,Boolean>> SRF_SIG = new WeakReference<ConcurrentHashMap<String, Boolean>>(
			new ConcurrentHashMap<String, Boolean>());

	@Autowired
	private CommandLookupService commandLookupService;
	@Override
	public ApiResult check(HttpServletRequest request) {
		
		
		if(!isNeedCheckSignature(request)) {
			// 不需要签名。 对一些不敏感，简单的接口可用设置不需要签名。 慎用！！
			return SUCC_RESULT;
		}
		
		// 防重发机制, 根据sig判断
		String uidStr = RequestUtils.get(request, HttpConstants.PARAM_UID);
		String methodName = McpUtils.getCmdMethodFromURI(request.getRequestURI());
		final long userId = NumberUtils.toInt(uidStr);
		final String reqSig = RequestUtils.get(request, HttpConstants.PARAM_SIG);
		final long timeOf10s = System.currentTimeMillis() / 10000;// 十秒为单位
		final String sig = String.format("%s.%s@%s.%s", userId, reqSig, timeOf10s,methodName);
		try {
			ConcurrentHashMap<String, Boolean> sigMap = SRF_SIG.get();
			if (sigMap == null) {// 空的时候，直接返回成功
				sigMap = new ConcurrentHashMap<String, Boolean>();
				SRF_SIG = new WeakReference<ConcurrentHashMap<String, Boolean>>(sigMap);
				logger.warn("CommandController.validateRequestFrequency: WeakReference empty.");
				return SUCC_RESULT;
			} 
			Boolean b = sigMap.get(sig);
			if (b != null) { // 是重发的请求，用户访问过于频繁
				logger.warn(String.format("sig repeat: %s, abort.", sig));
				return new ApiResult(ApiResultCode.E_SYS_REQUEST_TOO_FAST);
			}
			
			sigMap.put(sig, true);
		} catch (Throwable t) {
			logger.error("validateRequestFrequency", t);
			return new ApiResult(ApiResultCode.E_SYS_UNKNOWN);
		}
		
		return SUCC_RESULT;
	}
	
	
	/**
	 * @param request
	 * @return
	 * @author guohongtao
	 */
	private boolean isNeedCheckSignature(HttpServletRequest request) {
		String methodName = McpUtils.getCmdMethodFromURI(request.getRequestURI());
		
		String version = RequestUtils.get(request, HttpConstants.PARAM_VER);
		return this.commandLookupService.needCheckSignature(methodName, version);
	}


	public SignatureFrequencyChecker() {
		super();
		this.setOrder(4);
	}




}
